package com.lyd.sweet.mybatis.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.lyd.sweet.convert.BasicConvert;
import com.lyd.sweet.exception.SweetBasicException;
import com.lyd.sweet.model.BaseQueryDTO;
import com.lyd.sweet.model.BasicService;
import com.lyd.sweet.model.ServiceStatus;
import com.lyd.sweet.mybatis.SweetBaseMapper;
import com.lyd.sweet.mybatis.utils.PageUtil;
import org.springframework.dao.DataIntegrityViolationException;

import java.util.List;


/**
 * 基本服务接口（实现单表增删改查，分页查询）
 *
 * @author 木木
 **/
public abstract class AbstractBasicService<ENTITY, QUERY, DTO, VO> implements BasicService<QUERY, DTO, VO> {

    private final BasicConvert<ENTITY, QUERY, DTO, VO> basicConvert;
    private final SweetBaseMapper<ENTITY> sweetBaseMapper;

    protected AbstractBasicService(BasicConvert<ENTITY, QUERY, DTO, VO> basicConvert,
                                SweetBaseMapper<ENTITY> sweetBaseMapper) {
        this.basicConvert = basicConvert;
        this.sweetBaseMapper = sweetBaseMapper;
    }

    @Override
    public VO create(DTO dto) {
        try {
            ENTITY entity = this.entityHandler(dto);
            this.sweetBaseMapper.insertSelective(entity);
            return this.basicConvert.toVo(entity);
        } catch (DataIntegrityViolationException dataIntegrityViolationException) {
            throw new SweetBasicException(ServiceStatus.FAIL, "数据完整性违规异常，请检查关联字段是否正确", dataIntegrityViolationException);
        } catch (SweetBasicException sweetBasicException) {
            throw sweetBasicException;
        } catch (Throwable t) {
            throw new SweetBasicException(ServiceStatus.FAIL, "未知异常，请联系管理员", t);
        }
    }

    @Override
    public Boolean delete(Object id) {
        int deleteCount = this.sweetBaseMapper.deleteByPrimaryKey(id);
        if (deleteCount == 0) {
            throw new SweetBasicException(ServiceStatus.FAIL, "删除失败，记录不存在，id=" + id);
        }
        if (deleteCount < 0) {
            throw new SweetBasicException(ServiceStatus.FAIL, "删除失败，数据库异常，id=" + id);
        }
        return true;
    }

    @Override
    public Boolean update(DTO dto) {
        ENTITY entity = this.entityHandler(dto);
        int updateCount = this.sweetBaseMapper.updateByPrimaryKeySelective(entity);
        if (updateCount < 0) {
            throw new SweetBasicException(ServiceStatus.FAIL, "更新失败，数据库异常");
        }
        return true;
    }

    @Override
    public VO getById(Object id) {
        ENTITY entity =  this.sweetBaseMapper.selectByPrimaryKey(id);
        VO vo = this.basicConvert.toVo(entity);
        return vo;
    }

    @Override
    public List<VO> list(QUERY query) {
        ENTITY entity = this.basicConvert.toEntity(query);
        List<ENTITY> entities = this.sweetBaseMapper.select(entity);
        List<VO> list = this.basicConvert.toVoList(entities);
        return list;
    }

    @Override
    public PageInfo<VO> pages(QUERY query) {
        BaseQueryDTO dto = (BaseQueryDTO) query;
        Page page = PageUtil.buildQueryPage(dto);
        ENTITY entity = this.basicConvert.toEntity(query);
        List<ENTITY> entities = this.sweetBaseMapper.select(entity);
        return PageUtil.buildResult(page, this.basicConvert.toVoList(entities));
    }

    /**
     * @param dto
     * @return
     */
    protected ENTITY entityHandler(DTO dto) {
        return this.basicConvert.dtoToENTITY(dto);
    }
}
